﻿using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using Urs.Admin.Models.Common;
using Urs.Admin.Models.Settings;
using Urs.Core;
using Urs.Data.Domain.Orders;
using Urs.Data.Domain.Configuration;
using Urs.Services;
using Urs.Services.Common;
using Urs.Services.Configuration;
using Urs.Services.Users;
using Urs.Services.Directory;
using Urs.Services.Localization;
using Urs.Services.Logging;
using Urs.Services.Media;
using Urs.Services.Orders;
using Urs.Services.Security;
using Urs.Framework.Controllers;
using Urs.Framework.Extensions;
using Urs.Framework.Kendoui;

namespace Urs.Admin.Controllers
{
    [AdminAuthorize]
    public partial class SettingController : BaseAdminController
    {
        #region Fields

        private readonly ISettingService _settingService;
        private readonly IAddressService _addressService;
        private readonly ILocalizationService _localizationService;
        private readonly IUserService _userService;
        private readonly IActivityLogService _activityLogService;
        private readonly IPermissionService _permissionService;
        private readonly IWebHelper _webHelper;
        private readonly IMaintenanceService _maintenanceService;
        private ShippingSettings _shippingSettings;
        private StoreSettings _storeSettings;
        private RewardPointsSettings _rewardPointsSettings;
        private OrderSettings _orderSettings;
        private ShoppingCartSettings _shoppingCartSettings;
        private MediaSettings _mediaSettings;
        private UserSettings _userSettings;
        private AddressSettings _addressSettings;
        private TemplateSettings _templateSettings;
        private BillingAddressSettings _billingAddressSettings;
        private readonly StoreInformationSettings _storeInformationSettings;
        private readonly SecuritySettings _securitySettings;
        private readonly PdfSettings _pdfSettings;
        private readonly AdminAreaSettings _adminAreaSettings;
        private readonly ExternalAuthSettings _externalAuthSettings;
        private readonly CommonSettings _commonSettings;
        private readonly IAreaService _areaService;
        #endregion

        #region Constructors

        public SettingController(ISettingService settingService,
            StoreSettings storeSettings,
            IAddressService addressService,
            ILocalizationService localizationService,
            IUserService userService,
            IActivityLogService activityLogService,
            IPermissionService permissionService,
            IWebHelper webHelper,
            IMaintenanceService maintenanceService,
            ShippingSettings shippingSettings,
            RewardPointsSettings rewardPointsSettings,
             OrderSettings orderSettings,
            ShoppingCartSettings shoppingCartSettings,
            MediaSettings mediaSettings,
            UserSettings userSettings,
            AddressSettings addressSettings,
            BillingAddressSettings billingAddressSettings,
            StoreInformationSettings storeInformationSettings,
            SecuritySettings securitySettings,
            PdfSettings pdfSettings,
            AdminAreaSettings adminAreaSettings,
            ExternalAuthSettings externalAuthenticationSettings,
            CommonSettings commonSettings,
            IAreaService areaService,
            TemplateSettings templateSettings)
        {
            this._settingService = settingService;
            this._storeSettings = storeSettings;
            this._addressService = addressService;
            this._localizationService = localizationService;
            this._billingAddressSettings = billingAddressSettings;
            this._userService = userService;
            this._activityLogService = activityLogService;
            this._permissionService = permissionService;
            this._webHelper = webHelper;
            this._maintenanceService = maintenanceService;
            this._shippingSettings = shippingSettings;
            this._rewardPointsSettings = rewardPointsSettings;
            this._orderSettings = orderSettings;
            this._shoppingCartSettings = shoppingCartSettings;
            this._mediaSettings = mediaSettings;
            this._userSettings = userSettings;
            this._addressSettings = addressSettings;
            this._storeInformationSettings = storeInformationSettings;
            this._securitySettings = securitySettings;
            this._pdfSettings = pdfSettings;
            this._adminAreaSettings = adminAreaSettings;
            this._externalAuthSettings = externalAuthenticationSettings;
            this._commonSettings = commonSettings;
            this._areaService = areaService;
            this._templateSettings = templateSettings;
        }

        #endregion

        #region Methods

        public IActionResult Shipping()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = _shippingSettings.ToSettingsModel<ShippingSettingsModel>();

            model.ShippingExpressNames = string.Join(',', _shippingSettings.ActiveShippingExpressNames);

            //shipping origin
            var originAddress = _shippingSettings.ShippingOriginAddressId > 0
                                     ? _addressService.GetAddressById(_shippingSettings.ShippingOriginAddressId)
                                     : null;
            if (originAddress != null)
                model.ShippingOriginAddress = originAddress.ToModel<AddressModel>();
            else
                model.ShippingOriginAddress = new AddressModel();

            model.ShippingOriginAddress.ProvincesEnabled = true;
            model.ShippingOriginAddress.StreetAddressEnabled = true;
            model.ShippingOriginAddress.ZipPostalCodeEnabled = true;
            model.ShippingOriginAddress.ZipPostalCodeRequired = true;

            return View(model);
        }
        [HttpPost]
        public IActionResult Shipping(ShippingSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            _shippingSettings = model.ToSettings(_shippingSettings);

            _shippingSettings.ActiveShippingExpressNames = model.ShippingExpressNames.Split(',', ' ', '，').ToList();

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));

            //return RedirectToAction("Shipping");
            return Json(new { success = 1 });
        }

        public IActionResult Catalog()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = _storeSettings.ToSettingsModel<StoreSettingsModel>();
            model.FeaturedGoodsOrderByValues = _storeSettings.FeaturedGoodsOrderBy.ToSelectList();
            return View(model);
        }
        [HttpPost]
        public IActionResult Catalog(StoreSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            _storeSettings = model.ToSettings(_storeSettings);

            _settingService.SaveSetting(_storeSettings);

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));

            return Json(new { success = 1 });
        }

        public IActionResult Points()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = _rewardPointsSettings.ToSettingsModel<PointsSettingsModel>();
            model.PrimaryStoreCurrencyCode = string.Empty;
            return View(model);
        }
        [HttpPost]
        public IActionResult Points(PointsSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            model.PrimaryStoreCurrencyCode = string.Empty;

            _rewardPointsSettings = model.ToSettings(_rewardPointsSettings);
            _settingService.SaveSetting(_rewardPointsSettings);

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));

            //return View(model);
            return Json(new { success = 1 });
        }

        public IActionResult Order()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = _orderSettings.ToSettingsModel<OrderSettingsModel>();
            model.PrimaryStoreCurrencyCode = string.Empty;

            //parse return request actions
            for (int i = 0; i < _orderSettings.AfterSalesActions.Count; i++)
            {
                model.AfterSalesActionsParsed += _orderSettings.AfterSalesActions[i];
                if (i != _orderSettings.AfterSalesActions.Count - 1)
                    model.AfterSalesActionsParsed += ",";
            }
            //parse return request reasons
            for (int i = 0; i < _orderSettings.AfterSalesReasons.Count; i++)
            {
                model.AfterSalesReasonsParsed += _orderSettings.AfterSalesReasons[i];
                if (i != _orderSettings.AfterSalesReasons.Count - 1)
                    model.AfterSalesReasonsParsed += ",";
            }

            //order ident
            model.OrderIdent = _maintenanceService.GetTableIdent<Order>();

            return View(model);
        }
        [HttpPost]
        public IActionResult Order(OrderSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            if (ModelState.IsValid)
            {
                model.PrimaryStoreCurrencyCode = string.Empty;
                _orderSettings = model.ToSettings(_orderSettings);

                //parse return request actions
                _orderSettings.AfterSalesActions.Clear();
                if (!string.IsNullOrWhiteSpace(model.AfterSalesActionsParsed))
                    foreach (var returnAction in model.AfterSalesActionsParsed.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                        _orderSettings.AfterSalesActions.Add(returnAction);
                //parse return request reasons
                _orderSettings.AfterSalesReasons.Clear();
                if (!string.IsNullOrWhiteSpace(model.AfterSalesReasonsParsed))
                    foreach (var returnReason in model.AfterSalesReasonsParsed.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                        _orderSettings.AfterSalesReasons.Add(returnReason);

                _settingService.SaveSetting(_orderSettings);

                //order ident
                if (model.OrderIdent.HasValue)
                {
                    try
                    {
                        _maintenanceService.SetTableIdent<Order>(model.OrderIdent.Value);
                    }
                    catch (Exception exc)
                    {
                    }
                }
                //activity log
                _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));
            }
            else
            {
            }
            //return RedirectToAction("Order");
            return Json(new { success = 1 });
        }

        public IActionResult ShoppingCart()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = _shoppingCartSettings.ToSettingsModel<ShoppingCartSettingsModel>();
            return View(model);
        }
        [HttpPost]
        public IActionResult ShoppingCart(ShoppingCartSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            int starttime, middletime, endtime;
            starttime = System.Environment.TickCount;

            _shoppingCartSettings = model.ToSettings(_shoppingCartSettings);

            middletime = System.Environment.TickCount;

            _settingService.SaveSetting(_shoppingCartSettings);

            endtime = System.Environment.TickCount;

            //activity log
            _activityLogService.InsertActivity("EditSettings", string.Format("{0}  保存数据库使用时间：{1} 毫秒 转换时间:{2} 毫秒", _localizationService.GetResource("ActivityLog.EditSettings"), endtime - middletime, middletime - starttime));

            //return RedirectToAction("ShoppingCart");
            return Json(new { success = 1 });
        }

        public IActionResult Media()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = _mediaSettings.ToSettingsModel<MediaSettingsModel>();
            return View(model);
        }
        [HttpPost]
        public IActionResult Media(MediaSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            _mediaSettings = model.ToSettings(_mediaSettings);
            _settingService.SaveSetting(_mediaSettings);

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));
            //return RedirectToAction("Media");
            return Json(new { success = 1 });
        }
        [HttpPost, ActionName("Media")]
        [FormValueRequired("change-picture-storage")]
        public IActionResult ChangePictureStorage()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));
            return RedirectToAction("Media");
        }

        public IActionResult User()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            //merge settings
            var model = new UserSettingsModel();
            model.UserSettings = _userSettings.ToSettingsModel<UserSettingsModel.UserInfoSettingsModel>();
            model.AddressSettings = _addressSettings.ToSettingsModel<UserSettingsModel.AddressSettingsModel>();
            model.ExternalAuthenticationSettings.AutoRegisterEnabled = _externalAuthSettings.AutoRegisterEnabled;
            return View(model);
        }
        [HttpPost]
        public IActionResult User(UserSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            _userSettings = model.UserSettings.ToSettings(_userSettings);
            _settingService.SaveSetting(_userSettings);

            _addressSettings = model.AddressSettings.ToSettings(_addressSettings);
            _settingService.SaveSetting(_addressSettings);

            _externalAuthSettings.AutoRegisterEnabled = model.ExternalAuthenticationSettings.AutoRegisterEnabled;
            _settingService.SaveSetting(_externalAuthSettings);

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));
            return Json(new { success = 1 });
        }

        public IActionResult Common(string selectedTab)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            //store information
            var model = new CommonSettingsModel();
            model.StoreInformationSettings.StoreName = _storeInformationSettings.StoreName;
            model.StoreInformationSettings.StoreUrl = _storeInformationSettings.StoreUrl;
            model.StoreInformationSettings.StoreClosed = _storeInformationSettings.StoreClosed;
            model.StoreInformationSettings.StoreServiceTime = _storeInformationSettings.StoreServiceTime;
            model.StoreInformationSettings.ServiceTelePhone = _storeInformationSettings.ServiceTelePhone;
            model.StoreInformationSettings.OnlineConsultingCode = _storeInformationSettings.OnlineConsultingCode;
            model.StoreInformationSettings.CopyrightInfo = _storeInformationSettings.CopyrightInfo;
            model.StoreInformationSettings.ICPRecord = _storeInformationSettings.ICPRecord;
            model.StoreInformationSettings.StoreLogo1 = _storeInformationSettings.StoreLogo1;
            model.StoreInformationSettings.StoreLogo2 = _storeInformationSettings.StoreLogo2;
            model.StoreInformationSettings.StoreLogo3 = _storeInformationSettings.StoreLogo3;

            //security settings
            model.SecuritySettings.EncryptionKey = _securitySettings.EncryptionKey;
            if (_securitySettings.AdminAreaAllowedIpAddresses != null)
                for (int i = 0; i < _securitySettings.AdminAreaAllowedIpAddresses.Count; i++)
                {
                    model.SecuritySettings.AdminAreaAllowedIpAddresses += _securitySettings.AdminAreaAllowedIpAddresses[i];
                    if (i != _securitySettings.AdminAreaAllowedIpAddresses.Count - 1)
                        model.SecuritySettings.AdminAreaAllowedIpAddresses += ",";
                }
            model.SecuritySettings.HideAdminMenuItemsBasedOnPermissions = _securitySettings.HideAdminMenuItemsBasedOnPermissions;

            model.SecuritySettings.UseSsl = _securitySettings.ForceSslForAllPages;

            //PDF settings
            model.PdfSettings.Enabled = _pdfSettings.Enabled;
            model.PdfSettings.LetterPageSizeEnabled = _pdfSettings.LetterPageSizeEnabled;
            model.PdfSettings.LogoPictureId = _pdfSettings.LogoPictureId;

            ViewData["selectedTab"] = selectedTab;
            return View(model);
        }
        [HttpPost]
        public IActionResult Common(CommonSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            //store information
            _storeInformationSettings.StoreName = model.StoreInformationSettings.StoreName;
            if (model.StoreInformationSettings.StoreUrl == null)
                model.StoreInformationSettings.StoreUrl = "";
            _storeInformationSettings.StoreUrl = model.StoreInformationSettings.StoreUrl;
            //ensure we have "/" at the end
            if (!_storeInformationSettings.StoreUrl.EndsWith("/"))
                _storeInformationSettings.StoreUrl += "/";
            _storeInformationSettings.StoreServiceTime = model.StoreInformationSettings.StoreServiceTime;
            _storeInformationSettings.ServiceTelePhone = model.StoreInformationSettings.ServiceTelePhone;
            _storeInformationSettings.CopyrightInfo = model.StoreInformationSettings.CopyrightInfo;
            _storeInformationSettings.ICPRecord = model.StoreInformationSettings.ICPRecord;
            _storeInformationSettings.OnlineConsultingCode = model.StoreInformationSettings.OnlineConsultingCode;
            _storeInformationSettings.StoreLogo1 = model.StoreInformationSettings.StoreLogo1;
            _storeInformationSettings.StoreLogo2 = model.StoreInformationSettings.StoreLogo2;
            _storeInformationSettings.StoreLogo3 = model.StoreInformationSettings.StoreLogo3;
            _storeInformationSettings.StoreClosed = model.StoreInformationSettings.StoreClosed;
             _settingService.SaveSetting(_storeInformationSettings);

            //security settings
            if (_securitySettings.AdminAreaAllowedIpAddresses == null)
                _securitySettings.AdminAreaAllowedIpAddresses = new List<string>();
            _securitySettings.AdminAreaAllowedIpAddresses.Clear();
            if (!String.IsNullOrEmpty(model.SecuritySettings.AdminAreaAllowedIpAddresses))
                foreach (string s in model.SecuritySettings.AdminAreaAllowedIpAddresses.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                    if (!String.IsNullOrWhiteSpace(s))
                        _securitySettings.AdminAreaAllowedIpAddresses.Add(s.Trim());
            _securitySettings.HideAdminMenuItemsBasedOnPermissions = model.SecuritySettings.HideAdminMenuItemsBasedOnPermissions;
            _settingService.SaveSetting(_securitySettings);


            //save SSL settings
            try
            {
                if (AppDomain.CurrentDomain.IsFullyTrusted)
                {
                    //full trust
                    bool useSsl = _securitySettings.ForceSslForAllPages;
                }
                else
                {
                }
            }
            catch (Exception exc)
            {
            }

            //PDF settings
            _pdfSettings.Enabled = model.PdfSettings.Enabled;
            _pdfSettings.LetterPageSizeEnabled = model.PdfSettings.LetterPageSizeEnabled;
            _pdfSettings.LogoPictureId = model.PdfSettings.LogoPictureId;
            _settingService.SaveSetting(_pdfSettings);

            //full-text
            _commonSettings.CustomAttributeArray = new Dictionary<string, string>();
            _commonSettings.CustomAttributeArray.Add("Goods", "商品字段");
            _commonSettings.CustomAttributeArray.Add("User", "用户字段");
            _settingService.SaveSetting(_commonSettings);

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));
            return Json(new { success = 1 });
        }

        //all settings
        public IActionResult AllSettings()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = new AllSettingsListModel();
            return View(model);
        }
        [HttpPost]
        public IActionResult AllSettings(PageRequest command, AllSettingsListModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var query = _settingService
                .GetAllSettings()
                .OrderBy(x => x.Name).AsQueryable().Skip((command.Page - 1) * command.Limit).Take(command.Limit);

            if (!string.IsNullOrEmpty(model.Name))
                query = query.Where(s => s.Name.ToLowerInvariant().Contains(model.Name.ToLowerInvariant()));
            if (!string.IsNullOrEmpty(model.Value))
                query = query.Where(s => s.Value.ToLowerInvariant().Contains(model.Value.ToLowerInvariant()));

            var count = query.Count();
            var settings = query.Select(x => new SettingModel()
            {
                Id = x.Id,
                Name = x.Name,
                Value = x.Value
            }).ToList();

            var result = new ResponseResult
            {
                data = settings,
                count = count
            };
            return Json(result);
        }

        public IActionResult AllSettingsEdit()
        {
            var model = new SettingModel();
            return View(model);
        }

        public IActionResult SettingUpdate(SettingModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            if (model.Name != null)
                model.Name = model.Name.Trim();
            if (model.Value != null)
                model.Value = model.Value.Trim();

            if (!ModelState.IsValid)
            {
                return Json(new ResponseResult { msg = ModelState.SerializeErrors() });
            }

            var setting = _settingService.GetSettingById(model.Id);
            if (setting == null)
                return Json(new { error = 1 });
            if (setting.Name != model.Name)
                _settingService.DeleteSetting(setting);

            _settingService.SetSetting(model.Name, model.Value);

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));

            return Json(new { success = 1 });
        }

        public IActionResult SettingAdd(SettingModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            if (model.Name != null)
                model.Name = model.Name.Trim();
            if (model.Value != null)
                model.Value = model.Value.Trim();

            if (!ModelState.IsValid)
            {
                return Json(new ResponseResult { msg = ModelState.SerializeErrors() });
            }

            _settingService.SetSetting(model.Name, model.Value);

            //activity log
            _activityLogService.InsertActivity("AddNewSetting", _localizationService.GetResource("ActivityLog.AddNewSetting"), model.Name);

            return Json(new { success = 1 });
        }
        [HttpPost]
        public IActionResult SettingDelete(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var setting = _settingService.GetSettingById(id);
            if (setting == null)
                return Json(new { error = 1 });
            _settingService.DeleteSetting(setting);

            //activity log
            _activityLogService.InsertActivity("DeleteSetting", _localizationService.GetResource("ActivityLog.DeleteSetting"), setting.Name);

            return Json(new { success = 1 });
        }

        #endregion
    }
}
